﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Runtime.InteropServices;
using AxComInteropATLLib;
using System.Windows.Forms;
using System.ComponentModel;

namespace ComInteropWPF
{

    [ComImport]
    [Guid("00000112-0000-0000-C000-000000000046")]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IOleObject
    {
        void SetClientSite(IOleClientSite pClientSite);
        void GetClientSite(ref IOleClientSite ppClientSite);
        void SetHostNames(object szContainerApp, object szContainerObj);
        void Close(uint dwSaveOption);
        void SetMoniker(uint dwWhichMoniker, object pmk);
        void GetMoniker(uint dwAssign, uint dwWhichMoniker, object ppmk);
        void InitFromData(System.Runtime.InteropServices.ComTypes.IDataObject pDataObject, bool fCreation, uint dwReserved);
        void GetClipboardData(uint dwReserved, ref System.Runtime.InteropServices.ComTypes.IDataObject ppDataObject);
        void DoVerb(uint iVerb, uint lpmsg, object pActiveSite, uint lindex, uint hwndParent, uint lprcPosRect);
        void EnumVerbs(ref object ppEnumOleVerb);
        void Update();
        void IsUpToDate();
        void GetUserClassID(uint pClsid);
        void GetUserType(uint dwFormOfType, uint pszUserType);
        void SetExtent(uint dwDrawAspect, uint psizel);
        void GetExtent(uint dwDrawAspect, uint psizel);
        void Advise(object pAdvSink, uint pdwConnection);
        void Unadvise(uint dwConnection);
        void EnumAdvise(ref object ppenumAdvise);
        void GetMiscStatus(uint dwAspect, uint pdwStatus);
        void SetColorScheme(object pLogpal);
    };

    [ComImport]
    [Guid("00000118-0000-0000-C000-000000000046")]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IOleClientSite
    {
        void SaveObject();
        void GetMoniker(uint dwAssign, uint dwWhichMoniker, ref object ppmk);
        void GetContainer(ref object ppContainer);
        void ShowObject();
        void OnShowWindow(bool fShow);
        void RequestNewObjectLayout();
    }


    [ComImport]
    [Guid("B196B288-BAB4-101A-B69C-00AA00341D07")]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IOleControl
    {
        //struct tagCONTROLINFO
        //{
        //    ULONG cb; uint32
        //    HACCEL hAccel; intptr
        //    USHORT cAccel; ushort
        //    DWORD dwFlags; uint32
        //}
        void GetControlInfo(out object pCI);
        void OnMnemonic([In, MarshalAs(UnmanagedType.Struct)]ref tagMSG pMsg);
        void OnAmbientPropertyChange([In] int dispID);
        void FreezeEvents([In, MarshalAs(UnmanagedType.Bool)] bool bFreeze);
    }






    public enum DOCHOSTUITYPE
    {
        DOCHOSTUITYPE_BROWSE = 0,
        DOCHOSTUITYPE_AUTHOR = 1
    }

    public enum DOCHOSTUIDBLCLK
    {
        DOCHOSTUIDBLCLK_DEFAULT = 0,
        DOCHOSTUIDBLCLK_SHOWPROPERTIES = 1,
        DOCHOSTUIDBLCLK_SHOWCODE = 2
    }

    [Flags()]
    public enum DOCHOSTUIFLAG
    {
        DOCHOSTUIFLAG_DIALOG = 0x00000001,
        DOCHOSTUIFLAG_DISABLE_HELP_MENU = 0x00000002,
        DOCHOSTUIFLAG_NO3DBORDER = 0x00000004,
        DOCHOSTUIFLAG_SCROLL_NO = 0x00000008,
        DOCHOSTUIFLAG_DISABLE_SCRIPT_INACTIVE = 0x00000010,
        DOCHOSTUIFLAG_OPENNEWWIN = 0x00000020,
        DOCHOSTUIFLAG_DISABLE_OFFSCREEN = 0x00000040,
        DOCHOSTUIFLAG_FLAT_SCROLLBAR = 0x00000080,
        DOCHOSTUIFLAG_DIV_BLOCKDEFAULT = 0x00000100,
        DOCHOSTUIFLAG_ACTIVATE_CLIENTHIT_ONLY = 0x00000200,
        DOCHOSTUIFLAG_OVERRIDEBEHAVIORFACTORY = 0x00000400,
        DOCHOSTUIFLAG_CODEPAGELINKEDFONTS = 0x00000800,
        DOCHOSTUIFLAG_URL_ENCODING_DISABLE_UTF8 = 0x00001000,
        DOCHOSTUIFLAG_URL_ENCODING_ENABLE_UTF8 = 0x00002000,
        DOCHOSTUIFLAG_ENABLE_FORMS_AUTOCOMPLETE = 0x00004000,
        DOCHOSTUIFLAG_ENABLE_INPLACE_NAVIGATION = 0x00010000,
        DOCHOSTUIFLAG_IME_ENABLE_RECONVERSION = 0x00020000,
        DOCHOSTUIFLAG_THEME = 0x00040000,
        DOCHOSTUIFLAG_NOTHEME = 0x00080000,
        DOCHOSTUIFLAG_NOPICS = 0x00100000,
        DOCHOSTUIFLAG_NO3DOUTERBORDER = 0x00200000,
        DOCHOSTUIFLAG_DISABLE_EDIT_NS_FIXUP = 0x400000,
        DOCHOSTUIFLAG_LOCAL_MACHINE_ACCESS_CHECK = 0x800000,
        DOCHOSTUIFLAG_DISABLE_UNTRUSTEDPROTOCOL = 0x1000000
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct DOCHOSTUIINFO
    {
        public uint cbSize;
        public uint dwFlags;
        public uint dwDoubleClick;
        [MarshalAs(UnmanagedType.BStr)]
        public string pchHostCss;
        [MarshalAs(UnmanagedType.BStr)]
        public string pchHostNS;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct tagMSG
    {
        public IntPtr hwnd;
        public uint message;
        public uint wParam;
        public int lParam;
        public uint time;
        public tagPOINT pt;
    }
    // Added missing definitions of tagRECT/tagPOINT

    [StructLayout(LayoutKind.Sequential, Pack = 4)]
    public struct tagRECT
    {

        public int left;
        public int top;
        public int right;
        public int bottom;
    }

    [StructLayout(LayoutKind.Sequential, Pack = 4)]
    public struct tagPOINT
    {

        public int x;
        public int y;
    }

    [ComImport]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    [GuidAttribute("bd3f23c0-d43e-11cf-893b-00aa00bdce1a")]
    public interface IDocHostUIHandler
    {
        [PreserveSig]
        uint ShowContextMenu(
        uint dwID,
        ref tagPOINT ppt,
        [MarshalAs(UnmanagedType.IUnknown)]  object pcmdtReserved,
        [MarshalAs(UnmanagedType.IDispatch)] object pdispReserved
        );

        void GetHostInfo(ref DOCHOSTUIINFO pInfo);

        void ShowUI(uint dwID, ref object pActiveObject, ref object pCommandTarget, ref object pFrame, ref object pDoc);

        void HideUI();

        void UpdateUI();

        void EnableModeless(int fEnable);

        void OnDocWindowActivate(int fActivate);

        void OnFrameWindowActivate(int fActivate);

        void ResizeBorder(ref tagRECT prcBorder, int pUIWindow, int fFrameWindow);

        [PreserveSig]
        uint TranslateAccelerator(ref tagMSG lpMsg, ref Guid pguidCmdGroup, uint nCmdID);

        void GetOptionKeyPath([MarshalAs(UnmanagedType.BStr)] ref string pchKey, uint dw);

        uint GetDropTarget(int pDropTarget, ref int ppDropTarget);

        [PreserveSig]
        void GetExternal([MarshalAs(UnmanagedType.IDispatch)] out object ppDispatch);

        [PreserveSig]
        uint TranslateUrl(
        uint dwTranslate,
        [MarshalAs(UnmanagedType.BStr)] string pchURLIn,
        [MarshalAs(UnmanagedType.BStr)] ref string ppchURLOut
        );

        //IDataObject FilterDataObject(IDataObject pDO);
    }





    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            ComInteropWPFClass myComInteropWPFClass = new ComInteropWPFClass();

            // Create the interop host control.
            System.Windows.Forms.Integration.WindowsFormsHost myWindowsFormsHost = new System.Windows.Forms.Integration.WindowsFormsHost();

            // Create the ActiveX control.
            AxComControlATL myAxComControlATL = new AxComControlATL();

            // Assign the ActiveX control as the host control's child.
            myWindowsFormsHost.Child = myAxComControlATL;

            myAxComControlATL.CreateControl();

            AxHost myAxHost = myAxComControlATL as AxHost;

            object myObject = myAxHost.GetOcx();

            IOleObject myOleObject = myObject as IOleObject;
            myOleObject.SetClientSite((IOleClientSite)myComInteropWPFClass);

            IOleControl myControlObject = myObject as IOleControl;
            myControlObject.OnAmbientPropertyChange(100);

            //IOleControlSite myOleControlSite = myObject as IOleControlSite;
            //myOleControlSite.AmbientPropertyChanged(100);

            // Add the interop host control to the Grid
            // control's collection of child controls.
            this.GridForHosting.Children.Add(myWindowsFormsHost);
        }

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            ComInteropWPFClass myComInteropWPFClass = new ComInteropWPFClass();
            
            myComInteropWPFClass.createObject();

            // Add the interop host control to the Grid
            // control's collection of child controls.
            this.GridForHosting.Children.Add(myComInteropWPFClass.Object);
        }



    }

    [ComVisible(true), ClassInterface(ClassInterfaceType.AutoDual)]
    public class ComInteropWPFClass : IOleClientSite, INotifyPropertyChanged
    {
        internal void createObject()
        {
            // Create the interop host control.
            System.Windows.Forms.Integration.WindowsFormsHost myWindowsFormsHost = new System.Windows.Forms.Integration.WindowsFormsHost();

            // Create the ActiveX control.
            AxComControlATL myAxComControlATL = new AxComControlATL();

            // Assign the ActiveX control as the host control's child.
            myWindowsFormsHost.Child = myAxComControlATL;

            myAxComControlATL.CreateControl();

            AxHost myAxHost = myAxComControlATL as AxHost;

            object myObject = myAxHost.GetOcx();

            IOleObject myOleObject = myObject as IOleObject;
            myOleObject.SetClientSite(this);

            IOleControl myControlObject = myObject as IOleControl;
            myControlObject.OnAmbientPropertyChange(100);

            //IOleControlSite myOleControlSite = myObject as IOleControlSite;
            //myOleControlSite.AmbientPropertyChanged(100);

            Object = myWindowsFormsHost;
        }

        [ComVisible(true), DispId(100)]
        public int getAmbientProperty()
        {
            return 35;
        }

        private UIElement m_Object;

        public UIElement Object
        {
            get
            {
                return m_Object;
            }
            internal set
            {
                m_Object = value;
                RaisePropertyChanged("Object");
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;

        protected void RaisePropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }











        void IOleClientSite.SaveObject()
        {
            throw new NotImplementedException();
        }

        void IOleClientSite.GetMoniker(uint dwAssign, uint dwWhichMoniker, ref object ppmk)
        {
            throw new NotImplementedException();
        }

        void IOleClientSite.GetContainer(ref object ppContainer)
        {
            throw new NotImplementedException();
        }

        void IOleClientSite.ShowObject()
        {
            throw new NotImplementedException();
        }

        void IOleClientSite.OnShowWindow(bool fShow)
        {
            throw new NotImplementedException();
        }

        void IOleClientSite.RequestNewObjectLayout()
        {
            throw new NotImplementedException();
        }
    }


}
